package xyz.hzxiao.config;

import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import io.github.resilience4j.timelimiter.TimeLimiterRegistry;
import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

/**
 * @Author: scy
 * @Date: 2022-09-02 16:09
 */
@Configuration
public class BeanConfig {

    @Bean
    public ReactiveResilience4JCircuitBreakerFactory defaultCustomizer() {
        //默认超时规则,默认1s,不使用断路器超时规则可以设置大一点
        return new ReactiveResilience4JCircuitBreakerFactory(CircuitBreakerRegistry.of(
                CircuitBreakerConfig
                        .custom()
                        // 滑动窗口的类型为时间窗口
                        .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.TIME_BASED)
                        // 时间窗口的大小为60秒
                        .slidingWindowSize(60)
                        // 在单位时间窗口内最少需要5次调用才能开始进行统计计算
                        .minimumNumberOfCalls(5)
                        // 在单位时间窗口内调用失败率达到70%后会启动断路器
                        .failureRateThreshold(70)
                        // 允许断路器自动由打开状态转换为半开状态
                        .enableAutomaticTransitionFromOpenToHalfOpen()
                        // 在半开状态下允许进行正常调用的次数
                        .permittedNumberOfCallsInHalfOpenState(5)
                        // 断路器打开状态转换为半开状态需要等待60秒
                        .waitDurationInOpenState(Duration.ofSeconds(60))
                        // 所有异常都当作失败来处理
                        .recordExceptions(Throwable.class)
                        .build()),
                TimeLimiterRegistry.of(TimeLimiterConfig
                        .custom()
                        .timeoutDuration(Duration.ofSeconds(60))
                        .build()));
    }
}
